package pl.edu.pk.psb.controller;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import pl.edu.pk.psb.bc.bo.PolaczenieBo;
import pl.edu.pk.psb.bc.bo.WydarzenieBo;
import pl.edu.pk.psb.bc.bo.WyszukiwarkaPolaczenBo;
import pl.edu.pk.psb.bc.dto.PolaczenieDto;
import pl.edu.pk.psb.bc.dto.TrasaDto;
import pl.edu.pk.psb.bc.dto.WydarzenieDto;
import pl.edu.pk.psb.bc.util.ZnalezionePolaczenie;
import pl.edu.pk.psb.command.ZnajdzPolaczenieCommand;
import pl.edu.pk.psb.validator.WyszukiwarkaPolaczenValidator;

@Controller
public class WyszukiwarkaPolaczenController {

	@Autowired
	WyszukiwarkaPolaczenBo wyszukiwarkaBo;

	@Autowired
	WydarzenieBo wydarzenieBo;

	@Autowired
	PolaczenieBo polaczenieBo;

	@Autowired
	WyszukiwarkaPolaczenValidator walidator;

	@RequestMapping(value = "znajdzPolaczenie", method = RequestMethod.POST)
	public ModelAndView znajdzPolaczenie(
			@ModelAttribute("command") ZnajdzPolaczenieCommand cmd,
			BindingResult wynik) {
		ModelMap map = new ModelMap();
		walidator.validate(cmd, wynik);
		if (wynik.hasErrors()) {
			ZnajdzPolaczenieCommand command = cmd;
			map.put("command", command);
			return new ModelAndView("szukajPolaczenia", map);
		}

		WydarzenieDto wydarzenieDto = (wydarzenieBo.pobierzWydarzenie(Integer
				.parseInt(cmd.getMiastoDo())));
		String miastoDo = wydarzenieDto.getAdres().getMiasto();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(wydarzenieDto.getData());
		int przesiadki = Integer.parseInt(cmd.getLiczbaPrzesiadek());
		List<ZnalezionePolaczenie> lista = null;
		switch (cmd.getTypSzukania()) {
		case 0:
			lista = wyszukiwarkaBo.znajdzBezPrzesiadki(cmd.getMiastoOd(),
					miastoDo, calendar.get(Calendar.DAY_OF_WEEK), przesiadki);
			break;
		case 1:
			lista = wyszukiwarkaBo.znajdzNajtanszePolaczenie(cmd.getMiastoOd(),
					miastoDo, calendar.get(Calendar.DAY_OF_WEEK), przesiadki);
			break;
		case 2:
			lista = wyszukiwarkaBo.znajdzNajktorszePolaczenie(
					cmd.getMiastoOd(), miastoDo,
					calendar.get(Calendar.DAY_OF_WEEK), przesiadki);
			break;
		case 3:
			lista = wyszukiwarkaBo.znajdzNajszybszePolaczenie(
					cmd.getMiastoOd(), miastoDo,
					calendar.get(Calendar.DAY_OF_WEEK), przesiadki);
			break;
		}
		if(lista==null){
			lista = new ArrayList<ZnalezionePolaczenie>();
			lista = wyszukiwarkaBo.znajdzBezPrzesiadki(cmd.getMiastoOd(),
					miastoDo, calendar.get(Calendar.DAY_OF_WEEK), przesiadki);
			cmd.setTypSzukania(0);
		}
		
		if (cmd.getTypSzukania()==0 && lista!=null && lista.size() > 0){
			map.put("lista", lista);
			map.put("typSzukania", "bezposr");
		}
		else if (lista != null && lista.size() > 0) {
			for (ZnalezionePolaczenie z : lista) {
				ustawGodzineOdjazdu(z);
			}
			int koszt = lista.get(0).getKoszt();
			int odleglosc = lista.get(0).getOdleglosc();
			int czas = lista.get(0).getCzasJazdy();
			map.put("lista", lista);
			map.put("odleglosc", odleglosc);
			map.put("czasJazdy", czas);
			map.put("koszt", koszt);
		}else {
			map.put("blad", "blad");
		}
		return new ModelAndView("znalezionePolaczenia", map);
	}

	private void ustawGodzineOdjazdu(ZnalezionePolaczenie z) {
		String godzinaWyjazdu = "";
		if (z.getPolaczenie() != null) {
			for (TrasaDto trasa : z.getPolaczenie()
					.getListaPrzystankowNaTrasie()) {
				if (trasa.getPrzystanek().getId() == z.getPoprzedniPrzystanek()
						.getId()) {
					godzinaWyjazdu = trasa.getCzasOdjazdu().get(
							Calendar.HOUR_OF_DAY)
							+ ":" + trasa.getMinutaOdjazdu();
					break;
				}
			}
		}
		z.setGodzinaWyjazdu(godzinaWyjazdu);
	}

	@RequestMapping(value = "szukajPolaczenia")
	public ModelAndView szukajPolaczenia(@RequestParam Integer id) {
		ModelMap map = new ModelMap();
		map.put("id", id);
		map.put("command", new ZnajdzPolaczenieCommand());
		return new ModelAndView("szukajPolaczenia", map);
	}
}
